package sort;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import sort.algorithm.Sorter;
import sort.record.RandomRecordsFactory;
import sort.record.Records;
import sort.record.RecordsFactory;
import sort.result.SortResultSummarizer;
import sort.ui.components.ResultSummaryTableModel;
import sort.ui.components.SimpleDialog;
import sort.ui.components.SortRepeatControlWindow;
import sort.ui.components.TableWindow;

/**
 * @author masaru-gotou
 *
 */
public class SortRepeatMain {
	private Sorter sorter;
	private Records records;
	private TableWindow result_win;
	private ResultSummaryTableModel model;
	private SortRepeatControlWindow frame;
	private int repeats;
	private final SortResultSummarizer sum = new SortResultSummarizer();
	private Thread sortThread;
	private boolean stop;

	private static final String argoNames[] = {
		"sort.argorythm.BubbleSort",
//		"sort.argorythm.BucketSort",
		"sort.argorythm.InsertionSort",
		"sort.argorythm.QuickSort",
		"sort.argorythm.SelectionSort",
	};
	
	public SortRepeatMain(String title) {
		frame = new SortRepeatControlWindow(title);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setArgorythmNames(argoNames);
		
		frame.addStartActionListener(new StartActionListener());
		frame.addStopActionListener(new StopActionListener());
		
		frame.setEnabledStopButton(false);
		
		this.model = new ResultSummaryTableModel();
		result_win = new TableWindow("result list",model);
		
		frame.pack();

		result_win.setLocation(frame.getLocation().x+frame.getWidth(),
							frame.getLocation().y);
		result_win.pack();
	}
	
	private class StartActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent ev) {
			try {
				sorter = (Sorter)Class.forName(frame.getArgorythmName()).newInstance();
			} catch (Exception e) {
				SimpleDialog.showErrorMessageDialog(frame, e);
				e.printStackTrace();
				return;
			}
			RecordsFactory factory = RandomRecordsFactory.getInstance();
			
			records = factory.create(frame.getRecordCount());
			repeats = frame.getExecCount();
			
			if ( frame.enabledShowSort() ) {
				sorter.addObserver(frame);
				frame.drawRecords(records);
			}
			frame.setEnabledStartButton(false);
			frame.setEnabledStopButton(true);
			stop = false;
			sum.clear();
			sortThread = new Thread(new Runnable() {
				@Override
				public void run() {
					for ( int i=0; i<repeats; i++ ) {
						SortExecuter executer = new SortExecuter(sorter,records);
						executer.execute();
						sum.add(executer.getResult());
						if ( stop ) break;
					}
					callBackEndSort();
				}
			});
			sortThread.start();
		}
	}
	
	private void callBackEndSort() {
		model.add(sum.getSummary());
		frame.setEnabledStartButton(true);
		frame.setEnabledStopButton(false);
	}
	
	private class StopActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if ( sortThread.isAlive() ) {
				stop = true;
			}
			frame.setEnabledStartButton(true);
			frame.setEnabledStopButton(false);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		PropertyConfigurator.configure("log4j.properties");
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				SortRepeatMain main = new SortRepeatMain("Sort Demo");
				main.result_win.setVisible(true);
				main.frame.setVisible(true);
			}
		});
	}
}
